package com.boss.fileapp.controller;

import com.boss.api.dto.ApiResultDTO;
import com.boss.fileapp.service.OperateFileService;
import com.boss.fileapp.util.SftpConnect;
import com.boss.framework.exception.AppRuntimeException;
import com.jcraft.jsch.ChannelSftp;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

@RestSchema(schemaId = "toSFTPController")
@RestController
@RequestMapping(value = "/v1", produces = MediaType.APPLICATION_JSON)
public class ToSFTPController {
    /** 错误码 */
    private final static String ERROR_RSCODE = "140999";
    /**时间格式*/
    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMdd_HHmmss");
    /** 日志 */
    private static Logger logger = LoggerFactory.getLogger(ToSFTPController.class);

    @Value("${generateFilePath}")
    private String dirPath;

    @Autowired
    private OperateFileService operateFileService;
    @Autowired
    private SftpConnect connect;

    /**
     * 上传文件
     * 1）发生异常时，删除远端已接收的文件
     * 2）上传全部成功后，将本地文件删除
     *
     * @return
     */
    @PostMapping("/salary/salaryFile")
    public ApiResultDTO assetFlowPass(@RequestParam("province") String province,@RequestParam("sendBankCode") String sendBankCode) {
        ChannelSftp sftp = null;
        try {
            sftp = connect.priKeyConnect();
//            sftp = connect.connect(5);
            operateFileService.uploadOfferFile(sftp, province,sendBankCode);
            return ApiResultDTO.success("上传文件成功！");
        } catch (AppRuntimeException e){
            logger.warn("上传文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.warn("上传文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, "上传文件发生异常");
        } finally {
            connect.disconnect(sftp);
        }
    }

    /**
     * 生成报盘工资文件
     * 1）生成工资文件前，将本地和远端的目录清空
     * 2）发生异常时，将已经生成的本地文件删除
     *
     * @return
     */
    @PostMapping("/salary/generateSalaryFile")
    public ApiResultDTO generateSalaryFile(@RequestParam("province") String province,@RequestParam("sendBankCode") String sendBankCode) {
        try {
//                文件生成时间
            Date date = new Date();
            String ymdhms = SDF.format(date);
            operateFileService.generateOfferFile(province,sendBankCode,ymdhms);
            return ApiResultDTO.success("生成文件成功！");
        } catch (AppRuntimeException e){
            logger.warn("生成文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.warn("生成文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, "生成文件发生异常");
        }
    }

    /**
     * 生成并上传报盘工资文件（异常卡号人员）
     * 1）生成文件前，将本地和远端的目录清空
     * 2）发生异常时，将本地和远端的目录清空
     * @return
     */
    @PostMapping("/salary/generateBankPayBackFile")
    public ApiResultDTO generateBankPayBackFile(@RequestParam("personIds") List<String> personIds,
                                                @RequestParam("province") String province) {
        ChannelSftp sftp = null;
        //                文件生成时间
        Date date = new Date();
        String ymdhms = SDF.format(date);
        try {
            sftp = connect.priKeyConnect();
//            sftp = connect.connect(5);
            operateFileService.generateAndUploadBankPayBackFile(sftp, personIds, province,ymdhms);
            return ApiResultDTO.success("生成文件成功！");
        } catch (AppRuntimeException e){
            logger.warn("生成异常卡号人员工资文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.warn("生成异常卡号人员工资文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, "生成异常卡号人员工资文件发生异常");
        } finally {
            connect.disconnect(sftp);
        }
    }

    @GetMapping("/salary/exportSalaryFile")
    public ApiResultDTO exportSalaryFile(@RequestParam("fileName") String fileName,
                                         @RequestParam("province") String province,
                                         @RequestParam("sendBankCode") String sendBankCode,
                                         HttpServletResponse response){
        String zip = dirPath + province +"_"+sendBankCode+ "_" + fileName + ".zip";
        File zipFile = new File(zip);
        if(!zipFile.exists()){
            return ApiResultDTO.error("没有可导出的文件！");
        }
        try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream(zipFile));
            OutputStream outputStream = response.getOutputStream()) {
            byte[] bytes = new byte[1024 * 10];
            int len;
            while ((len = bis.read(bytes)) != -1){
                outputStream.write(bytes, 0, len);
            }
            outputStream.flush();
            return ApiResultDTO.success("生成文件成功！");
        } catch (Exception e) {
            logger.warn("导出工资文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, "导出工资文件发生异常");
        }
    }


    /**
     * 生成报盘工资文件
     * 1）生成工资文件前，将本地和远端的目录清空
     * 2）发生异常时，将已经生成的本地文件删除
     *
     * @return
     */
    @PostMapping("/salary/ungenerateSalaryFile")
    public ApiResultDTO ungenerateSalaryFile(@RequestParam("province") String province,@RequestParam("sendBankCode") String sendBankCode) {
        ChannelSftp sftp = null;
        try {
            sftp = connect.priKeyConnect();
//            sftp = connect.connect(5);
            //        清空本地的报盘文件
            //        上传之前先清空远端的报盘文件
            operateFileService.deleteRemoteHistoryFile(sftp, province,sendBankCode);
            operateFileService.deleteLocalHistoryFile(province,sendBankCode);
            //operateFileService.generateOfferFile(province,sendBankCode);
            return ApiResultDTO.success("撤销文件成功！");
        } catch (AppRuntimeException e){
            logger.warn("撤销文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, e.getMessage());
        } catch (Exception e) {
            logger.warn("撤销文件发生异常", e);
            return ApiResultDTO.error(ERROR_RSCODE, "撤销文件发生异常");
        } finally {
            connect.disconnect(sftp);
        }
    }

}
